1. Chr12

Divide the Chr12 Inversion into 3 groups

source("../Rscripts/BaseScripts.R")
library(ggforce)
library(cowplot)
library(ggvenn)
pcacols<-c("#fbb4ae","#b3cde3","#ccebc5")
pop_info<-read.csv("../Data/Sample_metadata_892pops.csv")
pops<-unique(pop_info$Population.Year)

#chr12 PCA info -use the plot to divide them into 3 groups each (non-TB and TB)
pca<-read.csv("../Output/PCA/pca_chr12.csv")
pca$yr.pop<-paste0(pca$pop,substr(pca$year, 3,4))
gp3<-pca[pca$PC2<=(-0.1), ] #45 (inversion group)
gp1<-pca[pca$PC1<0.02&pca$PC2>=(-0.02), ] #505
sampl<-c(gp1$Sample, gp3$Sample)
gp2<-pca[!(pca$Sample %in% sampl)&pca$pop!="TB",  ] #71

#TB
tb_gp1<-pca[pca$PC2>=(-0.007) & pca$pop=="TB",] #230
tb_gp2<-pca[pca$PC2<(-0.007)&pca$PC1>=0.03 & pca$pop=="TB",] #40
#one outlier
tb_gp3<-pca[pca$PC1<0.03 & pca$pop=="TB",]  #1

pca12<-pca[, c("Sample","pop","year","yr.pop","PC1","PC2","PC3")]
pca12$Group<-"Group1"
pca12$Group[pca12$Sample %in% gp2$Sample]<-"Group2"
pca12$Group[pca12$Sample %in% gp3$Sample]<-"Group3"
pca12$Group[pca12$Sample %in% tb_gp1$Sample]<-"TB_Group1"
pca12$Group[pca12$Sample %in% tb_gp2$Sample]<-"TB_Group2"
pca12$Group[pca12$Sample %in% tb_gp3$Sample]<-"TB_Group3"
write.csv(pca12, "../Output/PCA/chr12_PCAgroups.csv")

## Plot PCA plot with group names
C <- as.matrix(read.table(paste0("../Data/PCAangsd/MD7000_maf05_chr12.cov")))
e <- eigen(C)
chr12 <-data.frame(Sample=pop_info$Sample,pop=pop_info$pop,year=pop_info$Year.Collected,
                    PC1=e$vectors[,1],PC2=e$vectors[,2],
                    PC3=e$vectors[,3],PC4=e$vectors[,4], stringsAsFactors=FALSE)
prop_explained <- c()
for (s in e$values[1:4]) {
        prop_explained <- c(prop_explained,round(((s / sum(e$values))*100),2))
}

write.csv(prop_explained, "../Output/PCA/chr12_prop_explained.csv")
chr12$pop<-factor(chr12$pop, levels=c("TB","PWS","SS","BC","WA","CA"))
ggplot()+
    geom_point(data = chr12, aes(x = PC1, y = PC2, fill = pop, color = pop, shape = factor(year)), size = 3)+
    scale_shape_manual(values=c(23,25,3,3,21), name="Year")+
    scale_fill_manual(values=paste0(cols,"99"), guide="none")+
    scale_color_manual(values=cols, name="Population")+
    xlab(paste("PC 1: ", prop_explained[1],"%\n",sep = ""))+
    ylab(paste("PC 2: ", prop_explained[2],"%\n",sep = ""))+
    theme_bw()+ggtitle('Chr12')+
    stat_ellipse(data=pca12, aes(x=PC1, y=PC2, group=Group), level=0.99,color="gray50", size=0.2)+
    annotate("text", x=0, y=0.02, label="Group 1")+
    annotate("text", x=-0.05, y=-0.04, label="Group 2")+
    annotate("text", x=-0.04, y=-0.125, label="Group 3")+
    annotate("text", x=0.035, y=0.02, label="TB_group 1")+
    annotate("text", x=0.045, y=-0.05, label="TB_group 2")+
    annotate("text", x=0.035, y=-0.09, label="TB_group 3")
ggsave("../Output/PCA/Chr12_PCA_withGroups.png", width = 6.5, height = 4, dpi=300)


Proportion of Group 1-3 in each population/year

#Plot proportion for each population
pca12.1<-pca12[pca12$pop!="TB",]
pca12.2<-pca12[pca12$pop=="TB",]

pop.sum<-pca12.1 %>% count(Group, yr.pop)
pop.sum$yr.pop<-factor(pop.sum$yr.pop, levels=c("PWS91","PWS96","PWS07","PWS17","SS96","SS06","SS17","BC17","WA17","CA17"))

pop.sum2<-pca12.2 %>% count(Group, yr.pop)
pop.sum2$yr.pop<-factor(pop.sum2$yr.pop, levels=c("TB91","TB96","TB06","TB17"))

g1<-ggplot(data=pop.sum, aes(x=yr.pop, y=n, fill=factor(Group)))+
    geom_bar(position="fill", stat="identity")+
    scale_fill_manual(values=pcacols, guide='none')+
    theme_linedraw()+theme(legend.title = element_blank())+ylab("Proportion of individuals")+
    xlab("")+
    ggtitle("chr12")
g2<-ggplot(data=pop.sum2, aes(x=yr.pop, y=n, fill=factor(Group)))+
    geom_bar(position="fill", stat="identity")+
    scale_fill_manual(values=pcacols, labels=c("Group1","Group2","Group3"))+
    theme_linedraw()+theme(legend.title = element_blank())+ylab("")+
    xlab("")+
    ggtitle("")

full1<-ggdraw()+
    draw_plot(g1,x=0,y=0,width=0.57,height=1)+
    draw_plot(g2,0.57,0,0.42,1)+
    draw_plot_label(c("non TB", "TB"), x=c(0.275, 0.72), y=c(1, 1), size = 10)
save_plot(filename ="../Output/PCA/ch12_prop_in3groups.png", plot = full1,base_width = 10, base_height = 5, dpi=300)   

Compare heterozygosity per region per group per year using bcftools

The following code is referred as “Box1”

#Calculate heterozygosity per window using bcftools (het_stats_PWS91.sh)
# 
#subset chr12 without inversion into one 
vcftools --gzvcf Data/new_vcf/PH_DP600_7000_minQ20_minMQ30_NS0.5_maf05.vcf.gz --bed Data/chr12/chr12_withoutInversion.bed --out Data/new_vcf/PH_chr12_noInversion --recode --keep-INFO-all 

bcftools stats -s - /home/ktist/ph/data/new_vcf/MD7000/PH_chr12_noInversion.recode.vcf.gz | grep '^PSC' > /home/ktist/ph/data/new_vcf/MD7000/PH_chr12_noInversion_stats

bcftools stats -r chr12:17750000-25780000  -s - /home/ktist/ph/data/new_vcf/MD7000/PH_DP600_7000_minQ20_minMQ30_NS0.5_maf05.vcf.gz | grep '^PSC' > /home/ktist/ph/data/new_vcf/MD7000/PH_chr12_inversion_stats

Results of observed heterozygosity (Ho) per year for each group

  • Summarize Ho based on two regions (region1=Inversion vs. region2=Non-Inversion)
pop_info<-read.csv("../Data/Sample_metadata_892pops.csv")

popnames<-c("PWS91","PWS96","PWS07","PWS17")

## Read the stats files and create het summary
# Calculate Ho and He from bcftools stats output files (stats from PWSonly files)
sfiles<-list.files("../Data/chr12/", pattern="_stats")
Het<-data.frame()
Het_sum<-data.frame()
for (i in 1:length(sfiles)){
    df<-read.table(paste0("../Data/chr12/", sfiles[i]), sep="\t", header=F)
    pname<-gsub("_stats",'',sfiles[i])
    df<-df[,c(3:6)]
    colnames(df)<-c("Sample","nRefHom","nNonRefHom","nHets")
    df$p<-(2*df$nRefHom+df$nHets)/(rowSums(df[,c("nRefHom","nNonRefHom","nHets")])*2)
    df$q<-(2*df$nNonRefHom+df$nHets)/(rowSums(df[,c("nRefHom","nNonRefHom","nHets")])*2)
    
    df$He<-2*df$p*df$q
    df$Ho<-df$nHets/rowSums(df[,c("nRefHom","nNonRefHom","nHets")])
    
    #remove the TB
    df1<-df[!grepl("TB",df$Sample),]
    df$Group<-"Group1"
    df$Group[df$Sample %in% gp2$Sample]<-"Group2"
    df$Group[df$Sample %in% gp3$Sample]<-"Group3"
    write.csv(df,paste0("../Output/chr12/chr12_Hetero_",pname,"_maf05.csv"))
    df$region<-gsub("PH_chr12_",'',pname)
    Het<-rbind(Het, df)
    
    Ho<-aggregate(df[,"Ho"], by=list(df$Group), mean )
    He<-aggregate(df[,"He"], by=list(df$Group), mean )
    het<-cbind(Ho, He$x)
    colnames(het)<-c("Group","Ho","He")
    het$region<-gsub("PH_chr12_",'',pname)
    
    Het_sum<-rbind(Het_sum,het)
}
write.csv(Het_sum, "../Output/chr12/chr12_Heteroz_Inv_summary.csv")

gcols<-c("#FB687B","#48ABE3","#75BA76")


ggplot()+
    geom_boxplot(data=Het,aes(x=region, y=Ho, color=Group, fill=Group), position=position_dodge(width =0.8),outlier.alpha = 0.6, outlier.size = 1,width=0.7)+
    geom_point(data=Het_sum, aes(x=region, y=Ho, color=Group),position=position_dodge(width =0.8))+
    theme_minimal()+
    theme(panel.grid.major.x = element_blank(), legend.title = element_blank())+
    geom_vline(xintercept = c(1.5), color="gray70",size=0.3)+
    scale_color_manual(values=gcols)+
    scale_fill_manual(values=paste0(gcols, "66"))+xlab('')+
    scale_x_discrete(labels=c('Inversion',"Non-Inversion"))
ggsave("../Output/chr12/PWS_Chr12_Ho.in.tworegions.png", width =4.5, height=2.1 , dpi=300)



2. Look at Chr7 inversion

## Plot PCA plot with group names
#from PCAngsd.R:  
pc7<-read.csv("../Output/chr/DP7000/chr7_PCAgroups.csv", row.names = 1)
#swap group 1 to 3 (group1=most common, group3 =most outlier)
pc7$Group2<-pc7$Group
pc7$Group[pc7$Group2==1]<-"Group3"
pc7$Group[pc7$Group2==3]<-"Group1"
pc7$Group[pc7$Group2==2]<-"Group2"
pc7<-pc7[,-6]
C <- as.matrix(read.table(paste0("../Data/PCAangsd/MD7000_maf05_chr7.cov")))
e <- eigen(C)
chr7 <-data.frame(Sample=pop_info$Sample,pop=pop_info$pop,year=pop_info$year,
                    PC1=e$vectors[,1],PC2=e$vectors[,2],
                    PC3=e$vectors[,3],PC4=e$vectors[,4], stringsAsFactors=FALSE)
prop_explained <- c()
for (s in e$values[1:4]) {
        prop_explained <- c(prop_explained,round(((s / sum(e$values))*100),2))
}
write.csv(prop_explained, "../Output/PCA/chr7_prop_explained.csv")

#Create TB group for chr7
tb1<-chr7[chr7$PC2<=(-0.01)&chr7$pop=="TB",]
tb2<-chr7[chr7$PC2>(-0.01)&chr7$PC2<0.03&chr7$pop=="TB",]
tb3<-chr7[chr7$PC2>0.03&chr7$pop=="TB",]
tb1$Group<-"TB_Group1"
tb2$Group<-"TB_Group2"
tb3$Group<-"TB_Group3"
tb<-rbind(tb1, tb2, tb3)
tb<-merge(tb[,c("Group","Sample","pop")], pop_info[,c("Sample","Year.Collected","Population.Year")], by="Sample")
tb<-tb[,c("Group","Sample","pop","Year.Collected", "Population.Year")]
colnames(tb)[4:5]<-colnames(pca7)[4:5]
pc7<-rbind(pc7,tb)
pca7<-merge(pc7[,c("Sample","pop","year","yr.pop","Group")], chr7[,c("Sample","PC1","PC2","PC3")], by="Sample", all=T)
write.csv(pca7, "../Output/PCA/chr7_PCAgroups.csv")

#TB_Group3 shows up too large
## Remove the ellipse for TB_Group3
ggplot()+
    geom_point(data = ch7, aes(x = PC1, y = PC2, fill = pop, color = pop, shape = factor(year)), size = 3)+
    scale_shape_manual(values=c(23,25,3,3,21), name="Year")+
    scale_fill_manual(values=paste0(cols,"99"), guide="none")+
    scale_color_manual(values=cols, name="Population")+
    xlab(paste("PC 1: ", prop_explained[1],"%\n",sep = ""))+
    ylab(paste("PC 2: ", prop_explained[2],"%\n",sep = ""))+
    theme_bw()+ggtitle('Chr7')+
    stat_ellipse(data=ch7[ch7$Group!="TB_Group3",], aes(x=PC1, y=PC2, group=Group), level=0.999,color="gray50", size=0.2)+
    geom_ellipse(aes(x0=0.075, y0=0.07,  angle=45, a=0.02, b=0.022), color="gray50", size=0.2)+geom_path()+
    annotate("text", x=-0.035, y=-0.02, label="Group 1")+
    annotate("text", x=-0.035, y=0.04, label="Group 2")+
    annotate("text", x=0, y=0.125, label="Group 3")+
    annotate("text", x=0.065, y=-0.025, label="TB_group 1")+
    annotate("text", x=0.0895, y=0.02, label="TB_group 2")+
    annotate("text", x=0.075, y=0.1, label="TB_group 3")
ggsave("../Output/PCA/Chr7_PCA_withGroups.png", width = 6.5, height = 4.5, dpi=300)

#Plot proportion for each population
ch7.2<-ch7[ch7$pop=="TB",]
ch7.1<-ch7[ch7$pop!="TB",]

pop.sum1<-ch7.1 %>% count(Group, yr.pop)
pop.sum2<-ch7.2 %>% count(Group, yr.pop)

pop.sum1$yr.pop<-factor(pop.sum1$yr.pop, levels=c("PWS91","PWS96","PWS07","PWS17","SS96","SS06","SS17","BC17","WA17","CA17"))
pop.sum2$yr.pop<-factor(pop.sum2$yr.pop, levels=c("TB91","TB96","TB06","TB17"))
p1<-ggplot(data=pop.sum1, aes(x=yr.pop, y=n, fill=factor(Group)))+
    geom_bar(position="fill", stat="identity")+
    scale_fill_manual(values=pcacols, guide="none")+
    theme_linedraw()+theme(legend.title = element_blank())+ylab("Proportion of individuals")+
    xlab("")+
    ggtitle("chr7")
p2<-ggplot(data=pop.sum2, aes(x=yr.pop, y=n, fill=factor(Group)))+
    geom_bar(position="fill", stat="identity")+
    scale_fill_manual(values=pcacols, labels=c("Group1","Group2","Group3"))+
    theme_linedraw()+theme(legend.title = element_blank())+ylab("")+
    xlab("")+
    ggtitle("")

full<-ggdraw()+
    draw_plot(p1,x=0,y=0,width=0.57,height=1)+
    draw_plot(p2,0.57,0,0.42,1)+
    draw_plot_label(c("non TB", "TB"), x=c(0.275, 0.72), y=c(1, 1), size = 10)
save_plot(filename ="../Output/PCA/ch7_prop_in3groups.png", plot = full,base_width = 10, base_height = 5, dpi=300)   

Find the overlapping individuals (individulas with both inversions)

CA population

colors<-qualitative_hcl(8, palette="Dark3")

#1. CA pop
gp3c7<- pca7$Sample[pca7$Group=="Group3"&pca7$pop=="CA"] # one PWS07 sample
gp3c12<-pca12$Sample[pca12$Group=="Group3"&pca12$pop=="CA"] #one WA17 sample
x<-list(chr7=gp3c7,chr12=gp3c12)

p3<-ggvenn(x, fill_color = cols, stroke_size = 0.5, set_name_size = 4,text_size=3)+ggtitle("Group3")
ggsave("../Output/PCA/ch7_ch12_gp3_overlap.png", width=7, height=5, dpi=300)

gp2c7<- pca7$Sample[pca7$Group=="Group2"&pca7$pop=="CA"]
gp2c12<-pca12$Sample[pca12$Group=="Group2"&pca12$pop=="CA"]
x2<-list(chr7=gp2c7,chr12=gp2c12)
p2<-ggvenn(x2, fill_color = cols,stroke_size = 0.5, set_name_size = 4,text_size=3)+ggtitle("Group2")

gp1c7<- pca7$Sample[pca7$Group=="Group1"&pca7$pop=="CA"]
gp1c12<-pca12$Sample[pca12$Group=="Group1"&pca12$pop=="CA"]
x1<-list(chr7=gp1c7,chr12=gp1c12)
p1<-ggvenn(x1, fill_color = colors,stroke_size = 0.5, set_name_size = 4,text_size=3)+ggtitle("Group1")

vennCA<-ggdraw()+
    draw_plot(p1,x=0,y=0,width=0.33,height=1)+
    draw_plot(p2,0.33,0,0.33,1)+
    draw_plot(p3,0.66,0,0.33,1)
   # draw_plot_label(c("Group1", "Group2","Group3"), x=c(0,0.33,0.66), y=c(1, 1,1), size = 10)
save_plot(filename ="../Output/PCA/CA_group_overlap.png", plot = vennCA,base_width = 10, base_height = 5, dpi=300)   

Proportion of Individuals with Ch12 and Ch7 inversions

#proportion of all types (chr12 and chr7)
s1<-intersect(gp3c7,gp3c12)
s2<-gp3c7[!(gp3c7 %in% s1)]
s3<-gp3c12[!(gp3c12 %in% s1)]
s4<-intersect(gp2c7,gp2c12)
s5<-gp2c7[!(gp2c7 %in% s4)]
s6<-gp2c12[!(gp2c12 %in% s4)]
s7<-gp1c7
s8<-gp1c12

caGroup<-data.frame(cluster=c(rep("both-inv", times=length(s1)),rep("c7-inv", times=length(s2)),rep("c12-inv", times=length(s3)),rep("both-het", times=length(s4)),rep("c7-het", times=length(s5)),rep("c12-het", times=length(s6)),rep("c7-common", times=length(s7)),rep("c12-common", times=length(s8))),Sample=c(s1,s2,s3,s4,s5,s6,s7,s8) )

CAsum<-data.frame(table(caGroup$cluster))

# Compute the position of labels
CAsum$Var1<-factor(CAsum$Var1, levels=c("both-inv", "c7-inv","c12-inv","both-het","c7-het","c12-het","c7-common","c12-common"))
CAsum<-CAsum[order(CAsum$Var1),]
CAsum<- CAsum %>% 
  arrange(desc(Var1)) %>%
  mutate(prop = Freq / sum(CAsum$Freq) *100) %>%
  mutate(ypos = cumsum(prop)- 0.5*prop )

ggplot(CAsum, aes(x="", y=Freq, fill=Var1))+
    geom_bar(stat="identity", width=1,color="white")+
    coord_polar("y", start=0, direction=-1)+theme_void()+
    geom_text(aes(x=1.6,y = ypos, label = Var1), color = "gray20", size=4) +
     geom_text(aes(x=1, label = paste0(round(prop, digits = 1), " %")), color = "gray20", size=3, position = position_stack(vjust = .5) ) +
    scale_fill_brewer(palette="Set3", guide='none')
ggsave("../Output/PCA/CA_c7-c12-inversion-groups_piechart.png", width = 5, height=5, dpi=300)

PWS population

colors<-qualitative_hcl(8, palette="Dark3")
Error in qualitative_hcl(8, palette = "Dark3") : 
  could not find function "qualitative_hcl"




Individulas with chr12 inversion and chr7 inversion do not overalap.

LS0tCnRpdGxlOiAiSW52ZXJzaW9uIGNocjEyICYgY2hyNyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICAgIHRvYzogdHJ1ZSAKICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgICAgdGhlbWU6IGx1bWVuCiAgICAgIGhpZ2hsaWdodDogdGFuZ28KICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgIGRmX3ByaW50OiBwYWdlZApkYXRlOiAiMDcvMTIvMjAyMiIKLS0tCgojIDEuIENocjEyCiMjIERpdmlkZSB0aGUgQ2hyMTIgSW52ZXJzaW9uIGludG8gMyBncm91cHMgIAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRX0Kc291cmNlKCIuLi9Sc2NyaXB0cy9CYXNlU2NyaXB0cy5SIikKbGlicmFyeShnZ2ZvcmNlKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoZ2d2ZW5uKQpgYGAKCgoKYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCnBjYWNvbHM8LWMoIiNmYmI0YWUiLCIjYjNjZGUzIiwiI2NjZWJjNSIpCnBvcF9pbmZvPC1yZWFkLmNzdigiLi4vRGF0YS9TYW1wbGVfbWV0YWRhdGFfODkycG9wcy5jc3YiKQpwb3BzPC11bmlxdWUocG9wX2luZm8kUG9wdWxhdGlvbi5ZZWFyKQoKI2NocjEyIFBDQSBpbmZvIC11c2UgdGhlIHBsb3QgdG8gZGl2aWRlIHRoZW0gaW50byAzIGdyb3VwcyBlYWNoIChub24tVEIgYW5kIFRCKQpwY2E8LXJlYWQuY3N2KCIuLi9PdXRwdXQvUENBL3BjYV9jaHIxMi5jc3YiKQpwY2EkeXIucG9wPC1wYXN0ZTAocGNhJHBvcCxzdWJzdHIocGNhJHllYXIsIDMsNCkpCmdwMzwtcGNhW3BjYSRQQzI8PSgtMC4xKSwgXSAjNDUgKGludmVyc2lvbiBncm91cCkKZ3AxPC1wY2FbcGNhJFBDMTwwLjAyJnBjYSRQQzI+PSgtMC4wMiksIF0gIzUwNQpzYW1wbDwtYyhncDEkU2FtcGxlLCBncDMkU2FtcGxlKQpncDI8LXBjYVshKHBjYSRTYW1wbGUgJWluJSBzYW1wbCkmcGNhJHBvcCE9IlRCIiwgIF0gIzcxCgojVEIKdGJfZ3AxPC1wY2FbcGNhJFBDMj49KC0wLjAwNykgJiBwY2EkcG9wPT0iVEIiLF0gIzIzMAp0Yl9ncDI8LXBjYVtwY2EkUEMyPCgtMC4wMDcpJnBjYSRQQzE+PTAuMDMgJiBwY2EkcG9wPT0iVEIiLF0gIzQwCiNvbmUgb3V0bGllcgp0Yl9ncDM8LXBjYVtwY2EkUEMxPDAuMDMgJiBwY2EkcG9wPT0iVEIiLF0gICMxCgpwY2ExMjwtcGNhWywgYygiU2FtcGxlIiwicG9wIiwieWVhciIsInlyLnBvcCIsIlBDMSIsIlBDMiIsIlBDMyIpXQpwY2ExMiRHcm91cDwtIkdyb3VwMSIKcGNhMTIkR3JvdXBbcGNhMTIkU2FtcGxlICVpbiUgZ3AyJFNhbXBsZV08LSJHcm91cDIiCnBjYTEyJEdyb3VwW3BjYTEyJFNhbXBsZSAlaW4lIGdwMyRTYW1wbGVdPC0iR3JvdXAzIgpwY2ExMiRHcm91cFtwY2ExMiRTYW1wbGUgJWluJSB0Yl9ncDEkU2FtcGxlXTwtIlRCX0dyb3VwMSIKcGNhMTIkR3JvdXBbcGNhMTIkU2FtcGxlICVpbiUgdGJfZ3AyJFNhbXBsZV08LSJUQl9Hcm91cDIiCnBjYTEyJEdyb3VwW3BjYTEyJFNhbXBsZSAlaW4lIHRiX2dwMyRTYW1wbGVdPC0iVEJfR3JvdXAzIgp3cml0ZS5jc3YocGNhMTIsICIuLi9PdXRwdXQvUENBL2NocjEyX1BDQWdyb3Vwcy5jc3YiKQoKIyMgUGxvdCBQQ0EgcGxvdCB3aXRoIGdyb3VwIG5hbWVzCkMgPC0gYXMubWF0cml4KHJlYWQudGFibGUocGFzdGUwKCIuLi9EYXRhL1BDQWFuZ3NkL01ENzAwMF9tYWYwNV9jaHIxMi5jb3YiKSkpCmUgPC0gZWlnZW4oQykKY2hyMTIgPC1kYXRhLmZyYW1lKFNhbXBsZT1wb3BfaW5mbyRTYW1wbGUscG9wPXBvcF9pbmZvJHBvcCx5ZWFyPXBvcF9pbmZvJFllYXIuQ29sbGVjdGVkLAogICAgICAgICAgICAgICAgICAgIFBDMT1lJHZlY3RvcnNbLDFdLFBDMj1lJHZlY3RvcnNbLDJdLAogICAgICAgICAgICAgICAgICAgIFBDMz1lJHZlY3RvcnNbLDNdLFBDND1lJHZlY3RvcnNbLDRdLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQpwcm9wX2V4cGxhaW5lZCA8LSBjKCkKZm9yIChzIGluIGUkdmFsdWVzWzE6NF0pIHsKICAgICAgICBwcm9wX2V4cGxhaW5lZCA8LSBjKHByb3BfZXhwbGFpbmVkLHJvdW5kKCgocyAvIHN1bShlJHZhbHVlcykpKjEwMCksMikpCn0KCndyaXRlLmNzdihwcm9wX2V4cGxhaW5lZCwgIi4uL091dHB1dC9QQ0EvY2hyMTJfcHJvcF9leHBsYWluZWQuY3N2IikKY2hyMTIkcG9wPC1mYWN0b3IoY2hyMTIkcG9wLCBsZXZlbHM9YygiVEIiLCJQV1MiLCJTUyIsIkJDIiwiV0EiLCJDQSIpKQpnZ3Bsb3QoKSsKICAgIGdlb21fcG9pbnQoZGF0YSA9IGNocjEyLCBhZXMoeCA9IFBDMSwgeSA9IFBDMiwgZmlsbCA9IHBvcCwgY29sb3IgPSBwb3AsIHNoYXBlID0gZmFjdG9yKHllYXIpKSwgc2l6ZSA9IDMpKwogICAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDIzLDI1LDMsMywyMSksIG5hbWU9IlllYXIiKSsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1wYXN0ZTAoY29scywiOTkiKSwgZ3VpZGU9Im5vbmUiKSsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9Y29scywgbmFtZT0iUG9wdWxhdGlvbiIpKwogICAgeGxhYihwYXN0ZSgiUEMgMTogIiwgcHJvcF9leHBsYWluZWRbMV0sIiVcbiIsc2VwID0gIiIpKSsKICAgIHlsYWIocGFzdGUoIlBDIDI6ICIsIHByb3BfZXhwbGFpbmVkWzJdLCIlXG4iLHNlcCA9ICIiKSkrCiAgICB0aGVtZV9idygpK2dndGl0bGUoJ0NocjEyJykrCiAgICBzdGF0X2VsbGlwc2UoZGF0YT1wY2ExMiwgYWVzKHg9UEMxLCB5PVBDMiwgZ3JvdXA9R3JvdXApLCBsZXZlbD0wLjk5LGNvbG9yPSJncmF5NTAiLCBzaXplPTAuMikrCiAgICBhbm5vdGF0ZSgidGV4dCIsIHg9MCwgeT0wLjAyLCBsYWJlbD0iR3JvdXAgMSIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PS0wLjA1LCB5PS0wLjA0LCBsYWJlbD0iR3JvdXAgMiIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PS0wLjA0LCB5PS0wLjEyNSwgbGFiZWw9Ikdyb3VwIDMiKSsKICAgIGFubm90YXRlKCJ0ZXh0IiwgeD0wLjAzNSwgeT0wLjAyLCBsYWJlbD0iVEJfZ3JvdXAgMSIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PTAuMDQ1LCB5PS0wLjA1LCBsYWJlbD0iVEJfZ3JvdXAgMiIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PTAuMDM1LCB5PS0wLjA5LCBsYWJlbD0iVEJfZ3JvdXAgMyIpCmdnc2F2ZSgiLi4vT3V0cHV0L1BDQS9DaHIxMl9QQ0Ffd2l0aEdyb3Vwcy5wbmciLCB3aWR0aCA9IDYuNSwgaGVpZ2h0ID0gNCwgZHBpPTMwMCkKCmBgYAoKIVtdKC4uL091dHB1dC9QQ0EvQ2hyMTJfUENBX3dpdGhHcm91cHMucG5nKSAgCgoKPGJyPgoKIyMjIFByb3BvcnRpb24gb2YgR3JvdXAgMS0zIGluIGVhY2ggcG9wdWxhdGlvbi95ZWFyICAKCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNQbG90IHByb3BvcnRpb24gZm9yIGVhY2ggcG9wdWxhdGlvbgpwY2ExMi4xPC1wY2ExMltwY2ExMiRwb3AhPSJUQiIsXQpwY2ExMi4yPC1wY2ExMltwY2ExMiRwb3A9PSJUQiIsXQoKcG9wLnN1bTwtcGNhMTIuMSAlPiUgY291bnQoR3JvdXAsIHlyLnBvcCkKcG9wLnN1bSR5ci5wb3A8LWZhY3Rvcihwb3Auc3VtJHlyLnBvcCwgbGV2ZWxzPWMoIlBXUzkxIiwiUFdTOTYiLCJQV1MwNyIsIlBXUzE3IiwiU1M5NiIsIlNTMDYiLCJTUzE3IiwiQkMxNyIsIldBMTciLCJDQTE3IikpCgpwb3Auc3VtMjwtcGNhMTIuMiAlPiUgY291bnQoR3JvdXAsIHlyLnBvcCkKcG9wLnN1bTIkeXIucG9wPC1mYWN0b3IocG9wLnN1bTIkeXIucG9wLCBsZXZlbHM9YygiVEI5MSIsIlRCOTYiLCJUQjA2IiwiVEIxNyIpKQoKZzE8LWdncGxvdChkYXRhPXBvcC5zdW0sIGFlcyh4PXlyLnBvcCwgeT1uLCBmaWxsPWZhY3RvcihHcm91cCkpKSsKICAgIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgc3RhdD0iaWRlbnRpdHkiKSsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1wY2Fjb2xzLCBndWlkZT0nbm9uZScpKwogICAgdGhlbWVfbGluZWRyYXcoKSt0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpK3lsYWIoIlByb3BvcnRpb24gb2YgaW5kaXZpZHVhbHMiKSsKICAgIHhsYWIoIiIpKwogICAgZ2d0aXRsZSgiY2hyMTIiKQpnMjwtZ2dwbG90KGRhdGE9cG9wLnN1bTIsIGFlcyh4PXlyLnBvcCwgeT1uLCBmaWxsPWZhY3RvcihHcm91cCkpKSsKICAgIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgc3RhdD0iaWRlbnRpdHkiKSsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1wY2Fjb2xzLCBsYWJlbHM9YygiR3JvdXAxIiwiR3JvdXAyIiwiR3JvdXAzIikpKwogICAgdGhlbWVfbGluZWRyYXcoKSt0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpK3lsYWIoIiIpKwogICAgeGxhYigiIikrCiAgICBnZ3RpdGxlKCIiKQoKZnVsbDE8LWdnZHJhdygpKwogICAgZHJhd19wbG90KGcxLHg9MCx5PTAsd2lkdGg9MC41NyxoZWlnaHQ9MSkrCiAgICBkcmF3X3Bsb3QoZzIsMC41NywwLDAuNDIsMSkrCiAgICBkcmF3X3Bsb3RfbGFiZWwoYygibm9uIFRCIiwgIlRCIiksIHg9YygwLjI3NSwgMC43MiksIHk9YygxLCAxKSwgc2l6ZSA9IDEwKQpzYXZlX3Bsb3QoZmlsZW5hbWUgPSIuLi9PdXRwdXQvUENBL2NoMTJfcHJvcF9pbjNncm91cHMucG5nIiwgcGxvdCA9IGZ1bGwxLGJhc2Vfd2lkdGggPSAxMCwgYmFzZV9oZWlnaHQgPSA1LCBkcGk9MzAwKSAgIApgYGAKCiFbXSguLi9PdXRwdXQvUENBL2NoMTJfcHJvcF9pbjNncm91cHMucG5nKSAKCgoKIyMjIENvbXBhcmUgaGV0ZXJvenlnb3NpdHkgcGVyIHJlZ2lvbiBwZXIgZ3JvdXAgcGVyIHllYXIgdXNpbmcgYmNmdG9vbHMKVGhlIGZvbGxvd2luZyBjb2RlIGlzIHJlZmVycmVkIGFzICJCb3gxIgpgYGB7YmFzaCBldmFsPUZBTFNFLCBlY2hvPVRSVUV9CiNDYWxjdWxhdGUgaGV0ZXJvenlnb3NpdHkgcGVyIHdpbmRvdyB1c2luZyBiY2Z0b29scyAoaGV0X3N0YXRzX1BXUzkxLnNoKQojIAojc3Vic2V0IGNocjEyIHdpdGhvdXQgaW52ZXJzaW9uIGludG8gb25lIAp2Y2Z0b29scyAtLWd6dmNmIERhdGEvbmV3X3ZjZi9QSF9EUDYwMF83MDAwX21pblEyMF9taW5NUTMwX05TMC41X21hZjA1LnZjZi5neiAtLWJlZCBEYXRhL2NocjEyL2NocjEyX3dpdGhvdXRJbnZlcnNpb24uYmVkIC0tb3V0IERhdGEvbmV3X3ZjZi9QSF9jaHIxMl9ub0ludmVyc2lvbiAtLXJlY29kZSAtLWtlZXAtSU5GTy1hbGwgCgpiY2Z0b29scyBzdGF0cyAtcyAtIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvUEhfY2hyMTJfbm9JbnZlcnNpb24ucmVjb2RlLnZjZi5neiB8IGdyZXAgJ15QU0MnID4gL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9QSF9jaHIxMl9ub0ludmVyc2lvbl9zdGF0cwoKYmNmdG9vbHMgc3RhdHMgLXIgY2hyMTI6MTc3NTAwMDAtMjU3ODAwMDAgIC1zIC0gL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9QSF9EUDYwMF83MDAwX21pblEyMF9taW5NUTMwX05TMC41X21hZjA1LnZjZi5neiB8IGdyZXAgJ15QU0MnID4gL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9QSF9jaHIxMl9pbnZlcnNpb25fc3RhdHMKYGBgCgoKIyMjIFJlc3VsdHMgb2Ygb2JzZXJ2ZWQgaGV0ZXJvenlnb3NpdHkgKEhvKSBwZXIgeWVhciBmb3IgZWFjaCBncm91cAoqIFN1bW1hcml6ZSBIbyBiYXNlZCBvbiB0d28gcmVnaW9ucyAocmVnaW9uMT1JbnZlcnNpb24gdnMuIHJlZ2lvbjI9Tm9uLUludmVyc2lvbikKCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSxldmFsPUZBTFNFfQoKcG9wX2luZm88LXJlYWQuY3N2KCIuLi9EYXRhL1NhbXBsZV9tZXRhZGF0YV84OTJwb3BzLmNzdiIpCgpwb3BuYW1lczwtYygiUFdTOTEiLCJQV1M5NiIsIlBXUzA3IiwiUFdTMTciKQoKIyMgUmVhZCB0aGUgc3RhdHMgZmlsZXMgYW5kIGNyZWF0ZSBoZXQgc3VtbWFyeQojIENhbGN1bGF0ZSBIbyBhbmQgSGUgZnJvbSBiY2Z0b29scyBzdGF0cyBvdXRwdXQgZmlsZXMgKHN0YXRzIGZyb20gUFdTb25seSBmaWxlcykKc2ZpbGVzPC1saXN0LmZpbGVzKCIuLi9EYXRhL2NocjEyLyIsIHBhdHRlcm49Il9zdGF0cyIpCkhldDwtZGF0YS5mcmFtZSgpCkhldF9zdW08LWRhdGEuZnJhbWUoKQpmb3IgKGkgaW4gMTpsZW5ndGgoc2ZpbGVzKSl7CiAgICBkZjwtcmVhZC50YWJsZShwYXN0ZTAoIi4uL0RhdGEvY2hyMTIvIiwgc2ZpbGVzW2ldKSwgc2VwPSJcdCIsIGhlYWRlcj1GKQogICAgcG5hbWU8LWdzdWIoIl9zdGF0cyIsJycsc2ZpbGVzW2ldKQogICAgZGY8LWRmWyxjKDM6NildCiAgICBjb2xuYW1lcyhkZik8LWMoIlNhbXBsZSIsIm5SZWZIb20iLCJuTm9uUmVmSG9tIiwibkhldHMiKQogICAgZGYkcDwtKDIqZGYkblJlZkhvbStkZiRuSGV0cykvKHJvd1N1bXMoZGZbLGMoIm5SZWZIb20iLCJuTm9uUmVmSG9tIiwibkhldHMiKV0pKjIpCiAgICBkZiRxPC0oMipkZiRuTm9uUmVmSG9tK2RmJG5IZXRzKS8ocm93U3VtcyhkZlssYygiblJlZkhvbSIsIm5Ob25SZWZIb20iLCJuSGV0cyIpXSkqMikKICAgIAogICAgZGYkSGU8LTIqZGYkcCpkZiRxCiAgICBkZiRIbzwtZGYkbkhldHMvcm93U3VtcyhkZlssYygiblJlZkhvbSIsIm5Ob25SZWZIb20iLCJuSGV0cyIpXSkKICAgIAogICAgI3JlbW92ZSB0aGUgVEIKICAgIGRmMTwtZGZbIWdyZXBsKCJUQiIsZGYkU2FtcGxlKSxdCiAgICBkZiRHcm91cDwtIkdyb3VwMSIKICAgIGRmJEdyb3VwW2RmJFNhbXBsZSAlaW4lIGdwMiRTYW1wbGVdPC0iR3JvdXAyIgogICAgZGYkR3JvdXBbZGYkU2FtcGxlICVpbiUgZ3AzJFNhbXBsZV08LSJHcm91cDMiCiAgICB3cml0ZS5jc3YoZGYscGFzdGUwKCIuLi9PdXRwdXQvY2hyMTIvY2hyMTJfSGV0ZXJvXyIscG5hbWUsIl9tYWYwNS5jc3YiKSkKICAgIGRmJHJlZ2lvbjwtZ3N1YigiUEhfY2hyMTJfIiwnJyxwbmFtZSkKICAgIEhldDwtcmJpbmQoSGV0LCBkZikKICAgIAogICAgSG88LWFnZ3JlZ2F0ZShkZlssIkhvIl0sIGJ5PWxpc3QoZGYkR3JvdXApLCBtZWFuICkKICAgIEhlPC1hZ2dyZWdhdGUoZGZbLCJIZSJdLCBieT1saXN0KGRmJEdyb3VwKSwgbWVhbiApCiAgICBoZXQ8LWNiaW5kKEhvLCBIZSR4KQogICAgY29sbmFtZXMoaGV0KTwtYygiR3JvdXAiLCJIbyIsIkhlIikKICAgIGhldCRyZWdpb248LWdzdWIoIlBIX2NocjEyXyIsJycscG5hbWUpCiAgICAKICAgIEhldF9zdW08LXJiaW5kKEhldF9zdW0saGV0KQp9CndyaXRlLmNzdihIZXRfc3VtLCAiLi4vT3V0cHV0L2NocjEyL2NocjEyX0hldGVyb3pfSW52X3N1bW1hcnkuY3N2IikKCmdjb2xzPC1jKCIjRkI2ODdCIiwiIzQ4QUJFMyIsIiM3NUJBNzYiKQoKCmdncGxvdCgpKwogICAgZ2VvbV9ib3hwbG90KGRhdGE9SGV0LGFlcyh4PXJlZ2lvbiwgeT1IbywgY29sb3I9R3JvdXAsIGZpbGw9R3JvdXApLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aCA9MC44KSxvdXRsaWVyLmFscGhhID0gMC42LCBvdXRsaWVyLnNpemUgPSAxLHdpZHRoPTAuNykrCiAgICBnZW9tX3BvaW50KGRhdGE9SGV0X3N1bSwgYWVzKHg9cmVnaW9uLCB5PUhvLCBjb2xvcj1Hcm91cCkscG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGggPTAuOCkpKwogICAgdGhlbWVfbWluaW1hbCgpKwogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYygxLjUpLCBjb2xvcj0iZ3JheTcwIixzaXplPTAuMykrCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWdjb2xzKSsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1wYXN0ZTAoZ2NvbHMsICI2NiIpKSt4bGFiKCcnKSsKICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoJ0ludmVyc2lvbicsIk5vbi1JbnZlcnNpb24iKSkKZ2dzYXZlKCIuLi9PdXRwdXQvY2hyMTIvUFdTX0NocjEyX0hvLmluLnR3b3JlZ2lvbnMucG5nIiwgd2lkdGggPTQuNSwgaGVpZ2h0PTIuMSAsIGRwaT0zMDApCgpgYGAKIVtdKC4uL091dHB1dC9jaHIxMi9QV1NfQ2hyMTJfSG8uaW4udHdvcmVnaW9ucy5wbmcpICAKCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLGV2YWw9RkFMU0V9CiNDcmVhdGUgYSBmaWd1cmUKcG9wczwtYygiUFdTOTEiLCJQV1M5NiIsIlBXUzA3IiwiUFdTMTciLCIiKQoKSGV0PC1kYXRhLmZyYW1lKCkKZm9yIChpIGluIDE6bGVuZ3RoKHBvcHMpKXsKICAgIGRmPC1yZWFkLmNzdihwYXN0ZTAoIi4uL091dHB1dC9TdGF0c193aW5kb3cvUFdTb25seV9jaHIxNV9IZXRlcm96XyIscG9wc1tpXSwiX21hZjA1LmNzdiIpLCByb3cubmFtZXMgPSAxKQogICAgZGYkd2luZG93PC1hcy5pbnRlZ2VyKGdzdWIocGFzdGUwKHBvcHNbaV0sIl9zdGF0c18iKSwnJyxkZiR3aW5kb3dfaWQpKQogICAgZGYkbG9jPC0icmVnaW9uMSIKICAgIGRmJGxvY1tkZiR3aW5kb3c+MTY1XTwtInJlZ2lvbjIiCiAgICBkZiRwb3A8LXBvcHNbaV0KICAgIEhldDwtcmJpbmQoSGV0LGRmKSAgICAKfQoKZ2NvbHM8LWMoIiNGQjY4N0IiLCIjNDhBQkUzIiwiIzc1QkE3NiIpCkhldCRwb3A8LWZhY3RvcihIZXQkcG9wLCBsZXZlbHM9cG9wcykKI0hldF9zdW08LXJlYWQuY3N2KCIuLi9PdXRwdXQvU3RhdHNfd2luZG93L1BXU29ubHlfY2hyMTVfSGV0ZXJvX2dyb3VwX3N1bW1hcnkuY3N2Iiwgcm93Lm5hbWVzID0gMSkKCmNvbG5hbWVzKEhldF9zdW0pWzRdPC0icG9wIgpIZXRfc3VtJHBvcDwtZmFjdG9yKEhldF9zdW0kcG9wLCBsZXZlbHM9cG9wcykKCmdncGxvdCgpKwogICAgZ2VvbV9ib3hwbG90KGRhdGE9SGV0LGFlcyh4PWxvYywgeT1IbywgY29sb3I9R3JvdXAsIGZpbGw9R3JvdXApLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aCA9MC44KSxvdXRsaWVyLmFscGhhID0gMC42LCBvdXRsaWVyLnNpemUgPSAxLHdpZHRoPTAuNykrCiAgICBnZW9tX3BvaW50KGRhdGE9SGV0X3N1bSwgYWVzKHg9UmVnaW9uLCB5PUhvLCBjb2xvcj1Hcm91cCkscG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGggPTAuOCkpKwogICAgZmFjZXRfd3JhcCh+cG9wKSsKICAgIHRoZW1lX21pbmltYWwoKSsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkrCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKDEuNSksIGNvbG9yPSJncmF5NzAiLHNpemU9MC4zKSsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9Z2NvbHMpKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPXBhc3RlMChnY29scywgIjY2IikpK3hsYWIoJycpCmdnc2F2ZSgiLi4vT3V0cHV0L1BDQS9QV1NfQ2hyMTVfSG8uaW4udHdvcmVnaW9ucy5wbmciLCB3aWR0aCA9IDgsIGhlaWdodCA9IDcsIGRwaT0zMDApCmBgYAohW10oLi4vT3V0cHV0L1BDQS9QV1NfQ2hyMTVfSG8uaW4udHdvcmVnaW9ucy5wbmcpICAKCgo8YnI+IAo8YnI+CgojIDIuIExvb2sgYXQgQ2hyNyBpbnZlcnNpb24gICAgCgpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyBQbG90IFBDQSBwbG90IHdpdGggZ3JvdXAgbmFtZXMKI2Zyb20gUENBbmdzZC5SOiAgCnBjNzwtcmVhZC5jc3YoIi4uL091dHB1dC9jaHIvRFA3MDAwL2NocjdfUENBZ3JvdXBzLmNzdiIsIHJvdy5uYW1lcyA9IDEpCiNzd2FwIGdyb3VwIDEgdG8gMyAoZ3JvdXAxPW1vc3QgY29tbW9uLCBncm91cDMgPW1vc3Qgb3V0bGllcikKcGM3JEdyb3VwMjwtcGM3JEdyb3VwCnBjNyRHcm91cFtwYzckR3JvdXAyPT0xXTwtIkdyb3VwMyIKcGM3JEdyb3VwW3BjNyRHcm91cDI9PTNdPC0iR3JvdXAxIgpwYzckR3JvdXBbcGM3JEdyb3VwMj09Ml08LSJHcm91cDIiCnBjNzwtcGM3WywtNl0KQyA8LSBhcy5tYXRyaXgocmVhZC50YWJsZShwYXN0ZTAoIi4uL0RhdGEvUENBYW5nc2QvTUQ3MDAwX21hZjA1X2NocjcuY292IikpKQplIDwtIGVpZ2VuKEMpCmNocjcgPC1kYXRhLmZyYW1lKFNhbXBsZT1wb3BfaW5mbyRTYW1wbGUscG9wPXBvcF9pbmZvJHBvcCx5ZWFyPXBvcF9pbmZvJHllYXIsCiAgICAgICAgICAgICAgICAgICAgUEMxPWUkdmVjdG9yc1ssMV0sUEMyPWUkdmVjdG9yc1ssMl0sCiAgICAgICAgICAgICAgICAgICAgUEMzPWUkdmVjdG9yc1ssM10sUEM0PWUkdmVjdG9yc1ssNF0sIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpCnByb3BfZXhwbGFpbmVkIDwtIGMoKQpmb3IgKHMgaW4gZSR2YWx1ZXNbMTo0XSkgewogICAgICAgIHByb3BfZXhwbGFpbmVkIDwtIGMocHJvcF9leHBsYWluZWQscm91bmQoKChzIC8gc3VtKGUkdmFsdWVzKSkqMTAwKSwyKSkKfQp3cml0ZS5jc3YocHJvcF9leHBsYWluZWQsICIuLi9PdXRwdXQvUENBL2NocjdfcHJvcF9leHBsYWluZWQuY3N2IikKCiNDcmVhdGUgVEIgZ3JvdXAgZm9yIGNocjcKdGIxPC1jaHI3W2NocjckUEMyPD0oLTAuMDEpJmNocjckcG9wPT0iVEIiLF0KdGIyPC1jaHI3W2NocjckUEMyPigtMC4wMSkmY2hyNyRQQzI8MC4wMyZjaHI3JHBvcD09IlRCIixdCnRiMzwtY2hyN1tjaHI3JFBDMj4wLjAzJmNocjckcG9wPT0iVEIiLF0KdGIxJEdyb3VwPC0iVEJfR3JvdXAxIgp0YjIkR3JvdXA8LSJUQl9Hcm91cDIiCnRiMyRHcm91cDwtIlRCX0dyb3VwMyIKdGI8LXJiaW5kKHRiMSwgdGIyLCB0YjMpCnRiPC1tZXJnZSh0YlssYygiR3JvdXAiLCJTYW1wbGUiLCJwb3AiKV0sIHBvcF9pbmZvWyxjKCJTYW1wbGUiLCJZZWFyLkNvbGxlY3RlZCIsIlBvcHVsYXRpb24uWWVhciIpXSwgYnk9IlNhbXBsZSIpCnRiPC10YlssYygiR3JvdXAiLCJTYW1wbGUiLCJwb3AiLCJZZWFyLkNvbGxlY3RlZCIsICJQb3B1bGF0aW9uLlllYXIiKV0KY29sbmFtZXModGIpWzQ6NV08LWNvbG5hbWVzKHBjYTcpWzQ6NV0KcGM3PC1yYmluZChwYzcsdGIpCnBjYTc8LW1lcmdlKHBjN1ssYygiU2FtcGxlIiwicG9wIiwieWVhciIsInlyLnBvcCIsIkdyb3VwIildLCBjaHI3WyxjKCJTYW1wbGUiLCJQQzEiLCJQQzIiLCJQQzMiKV0sIGJ5PSJTYW1wbGUiLCBhbGw9VCkKd3JpdGUuY3N2KHBjYTcsICIuLi9PdXRwdXQvUENBL2NocjdfUENBZ3JvdXBzLmNzdiIpCgojVEJfR3JvdXAzIHNob3dzIHVwIHRvbyBsYXJnZQojIyBSZW1vdmUgdGhlIGVsbGlwc2UgZm9yIFRCX0dyb3VwMwpnZ3Bsb3QoKSsKICAgIGdlb21fcG9pbnQoZGF0YSA9IGNoNywgYWVzKHggPSBQQzEsIHkgPSBQQzIsIGZpbGwgPSBwb3AsIGNvbG9yID0gcG9wLCBzaGFwZSA9IGZhY3Rvcih5ZWFyKSksIHNpemUgPSAzKSsKICAgIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygyMywyNSwzLDMsMjEpLCBuYW1lPSJZZWFyIikrCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9cGFzdGUwKGNvbHMsIjk5IiksIGd1aWRlPSJub25lIikrCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWNvbHMsIG5hbWU9IlBvcHVsYXRpb24iKSsKICAgIHhsYWIocGFzdGUoIlBDIDE6ICIsIHByb3BfZXhwbGFpbmVkWzFdLCIlXG4iLHNlcCA9ICIiKSkrCiAgICB5bGFiKHBhc3RlKCJQQyAyOiAiLCBwcm9wX2V4cGxhaW5lZFsyXSwiJVxuIixzZXAgPSAiIikpKwogICAgdGhlbWVfYncoKStnZ3RpdGxlKCdDaHI3JykrCiAgICBzdGF0X2VsbGlwc2UoZGF0YT1jaDdbY2g3JEdyb3VwIT0iVEJfR3JvdXAzIixdLCBhZXMoeD1QQzEsIHk9UEMyLCBncm91cD1Hcm91cCksIGxldmVsPTAuOTk5LGNvbG9yPSJncmF5NTAiLCBzaXplPTAuMikrCiAgICBnZW9tX2VsbGlwc2UoYWVzKHgwPTAuMDc1LCB5MD0wLjA3LCAgYW5nbGU9NDUsIGE9MC4wMiwgYj0wLjAyMiksIGNvbG9yPSJncmF5NTAiLCBzaXplPTAuMikrZ2VvbV9wYXRoKCkrCiAgICBhbm5vdGF0ZSgidGV4dCIsIHg9LTAuMDM1LCB5PS0wLjAyLCBsYWJlbD0iR3JvdXAgMSIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PS0wLjAzNSwgeT0wLjA0LCBsYWJlbD0iR3JvdXAgMiIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PTAsIHk9MC4xMjUsIGxhYmVsPSJHcm91cCAzIikrCiAgICBhbm5vdGF0ZSgidGV4dCIsIHg9MC4wNjUsIHk9LTAuMDI1LCBsYWJlbD0iVEJfZ3JvdXAgMSIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PTAuMDg5NSwgeT0wLjAyLCBsYWJlbD0iVEJfZ3JvdXAgMiIpKwogICAgYW5ub3RhdGUoInRleHQiLCB4PTAuMDc1LCB5PTAuMSwgbGFiZWw9IlRCX2dyb3VwIDMiKQpnZ3NhdmUoIi4uL091dHB1dC9QQ0EvQ2hyN19QQ0Ffd2l0aEdyb3Vwcy5wbmciLCB3aWR0aCA9IDYuNSwgaGVpZ2h0ID0gNC41LCBkcGk9MzAwKQoKYGBgCgohW10oLi4vT3V0cHV0L1BDQS9DaHI3X1BDQV93aXRoR3JvdXBzLnBuZykgIAoKCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNQbG90IHByb3BvcnRpb24gZm9yIGVhY2ggcG9wdWxhdGlvbgpjaDcuMjwtY2g3W2NoNyRwb3A9PSJUQiIsXQpjaDcuMTwtY2g3W2NoNyRwb3AhPSJUQiIsXQoKcG9wLnN1bTE8LWNoNy4xICU+JSBjb3VudChHcm91cCwgeXIucG9wKQpwb3Auc3VtMjwtY2g3LjIgJT4lIGNvdW50KEdyb3VwLCB5ci5wb3ApCgpwb3Auc3VtMSR5ci5wb3A8LWZhY3Rvcihwb3Auc3VtMSR5ci5wb3AsIGxldmVscz1jKCJQV1M5MSIsIlBXUzk2IiwiUFdTMDciLCJQV1MxNyIsIlNTOTYiLCJTUzA2IiwiU1MxNyIsIkJDMTciLCJXQTE3IiwiQ0ExNyIpKQpwb3Auc3VtMiR5ci5wb3A8LWZhY3Rvcihwb3Auc3VtMiR5ci5wb3AsIGxldmVscz1jKCJUQjkxIiwiVEI5NiIsIlRCMDYiLCJUQjE3IikpCnAxPC1nZ3Bsb3QoZGF0YT1wb3Auc3VtMSwgYWVzKHg9eXIucG9wLCB5PW4sIGZpbGw9ZmFjdG9yKEdyb3VwKSkpKwogICAgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiLCBzdGF0PSJpZGVudGl0eSIpKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPXBjYWNvbHMsIGd1aWRlPSJub25lIikrCiAgICB0aGVtZV9saW5lZHJhdygpK3RoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkreWxhYigiUHJvcG9ydGlvbiBvZiBpbmRpdmlkdWFscyIpKwogICAgeGxhYigiIikrCiAgICBnZ3RpdGxlKCJjaHI3IikKcDI8LWdncGxvdChkYXRhPXBvcC5zdW0yLCBhZXMoeD15ci5wb3AsIHk9biwgZmlsbD1mYWN0b3IoR3JvdXApKSkrCiAgICBnZW9tX2Jhcihwb3NpdGlvbj0iZmlsbCIsIHN0YXQ9ImlkZW50aXR5IikrCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9cGNhY29scywgbGFiZWxzPWMoIkdyb3VwMSIsIkdyb3VwMiIsIkdyb3VwMyIpKSsKICAgIHRoZW1lX2xpbmVkcmF3KCkrdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSt5bGFiKCIiKSsKICAgIHhsYWIoIiIpKwogICAgZ2d0aXRsZSgiIikKCmZ1bGw8LWdnZHJhdygpKwogICAgZHJhd19wbG90KHAxLHg9MCx5PTAsd2lkdGg9MC41NyxoZWlnaHQ9MSkrCiAgICBkcmF3X3Bsb3QocDIsMC41NywwLDAuNDIsMSkrCiAgICBkcmF3X3Bsb3RfbGFiZWwoYygibm9uIFRCIiwgIlRCIiksIHg9YygwLjI3NSwgMC43MiksIHk9YygxLCAxKSwgc2l6ZSA9IDEwKQpzYXZlX3Bsb3QoZmlsZW5hbWUgPSIuLi9PdXRwdXQvUENBL2NoN19wcm9wX2luM2dyb3Vwcy5wbmciLCBwbG90ID0gZnVsbCxiYXNlX3dpZHRoID0gMTAsIGJhc2VfaGVpZ2h0ID0gNSwgZHBpPTMwMCkgICAKYGBgCgohW10oLi4vT3V0cHV0L1BDQS9jaDdfcHJvcF9pbjNncm91cHMucG5nKQoKIyMgRmluZCB0aGUgb3ZlcmxhcHBpbmcgaW5kaXZpZHVhbHMgIChpbmRpdmlkdWxhcyB3aXRoIGJvdGggaW52ZXJzaW9ucykKCiMjIyBDQSBwb3B1bGF0aW9uCgpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKY29sb3JzPC1xdWFsaXRhdGl2ZV9oY2woOCwgcGFsZXR0ZT0iRGFyazMiKQoKIzEuIENBIHBvcApncDNjNzwtIHBjYTckU2FtcGxlW3BjYTckR3JvdXA9PSJHcm91cDMiJnBjYTckcG9wPT0iQ0EiXSAjIG9uZSBQV1MwNyBzYW1wbGUKZ3AzYzEyPC1wY2ExMiRTYW1wbGVbcGNhMTIkR3JvdXA9PSJHcm91cDMiJnBjYTEyJHBvcD09IkNBIl0gI29uZSBXQTE3IHNhbXBsZQp4PC1saXN0KGNocjc9Z3AzYzcsY2hyMTI9Z3AzYzEyKQoKcDM8LWdndmVubih4LCBmaWxsX2NvbG9yID0gY29scywgc3Ryb2tlX3NpemUgPSAwLjUsIHNldF9uYW1lX3NpemUgPSA0LHRleHRfc2l6ZT0zKStnZ3RpdGxlKCJHcm91cDMiKQpnZ3NhdmUoIi4uL091dHB1dC9QQ0EvY2g3X2NoMTJfZ3AzX292ZXJsYXAucG5nIiwgd2lkdGg9NywgaGVpZ2h0PTUsIGRwaT0zMDApCgpncDJjNzwtIHBjYTckU2FtcGxlW3BjYTckR3JvdXA9PSJHcm91cDIiJnBjYTckcG9wPT0iQ0EiXQpncDJjMTI8LXBjYTEyJFNhbXBsZVtwY2ExMiRHcm91cD09Ikdyb3VwMiImcGNhMTIkcG9wPT0iQ0EiXQp4MjwtbGlzdChjaHI3PWdwMmM3LGNocjEyPWdwMmMxMikKcDI8LWdndmVubih4MiwgZmlsbF9jb2xvciA9IGNvbHMsc3Ryb2tlX3NpemUgPSAwLjUsIHNldF9uYW1lX3NpemUgPSA0LHRleHRfc2l6ZT0zKStnZ3RpdGxlKCJHcm91cDIiKQoKZ3AxYzc8LSBwY2E3JFNhbXBsZVtwY2E3JEdyb3VwPT0iR3JvdXAxIiZwY2E3JHBvcD09IkNBIl0KZ3AxYzEyPC1wY2ExMiRTYW1wbGVbcGNhMTIkR3JvdXA9PSJHcm91cDEiJnBjYTEyJHBvcD09IkNBIl0KeDE8LWxpc3QoY2hyNz1ncDFjNyxjaHIxMj1ncDFjMTIpCnAxPC1nZ3Zlbm4oeDEsIGZpbGxfY29sb3IgPSBjb2xvcnMsc3Ryb2tlX3NpemUgPSAwLjUsIHNldF9uYW1lX3NpemUgPSA0LHRleHRfc2l6ZT0zKStnZ3RpdGxlKCJHcm91cDEiKQoKdmVubkNBPC1nZ2RyYXcoKSsKICAgIGRyYXdfcGxvdChwMSx4PTAseT0wLHdpZHRoPTAuMzMsaGVpZ2h0PTEpKwogICAgZHJhd19wbG90KHAyLDAuMzMsMCwwLjMzLDEpKwogICAgZHJhd19wbG90KHAzLDAuNjYsMCwwLjMzLDEpCiAgICMgZHJhd19wbG90X2xhYmVsKGMoIkdyb3VwMSIsICJHcm91cDIiLCJHcm91cDMiKSwgeD1jKDAsMC4zMywwLjY2KSwgeT1jKDEsIDEsMSksIHNpemUgPSAxMCkKc2F2ZV9wbG90KGZpbGVuYW1lID0iLi4vT3V0cHV0L1BDQS9DQV9ncm91cF9vdmVybGFwLnBuZyIsIHBsb3QgPSB2ZW5uQ0EsYmFzZV93aWR0aCA9IDEwLCBiYXNlX2hlaWdodCA9IDUsIGRwaT0zMDApICAgCmBgYAohW10oLi4vT3V0cHV0L1BDQS9DQV9ncm91cF9vdmVybGFwLnBuZykKCiMjIyBQcm9wb3J0aW9uIG9mIEluZGl2aWR1YWxzIHdpdGggQ2gxMiBhbmQgQ2g3IGludmVyc2lvbnMKCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNwcm9wb3J0aW9uIG9mIGFsbCB0eXBlcyAoY2hyMTIgYW5kIGNocjcpCnMxPC1pbnRlcnNlY3QoZ3AzYzcsZ3AzYzEyKQpzMjwtZ3AzYzdbIShncDNjNyAlaW4lIHMxKV0KczM8LWdwM2MxMlshKGdwM2MxMiAlaW4lIHMxKV0KczQ8LWludGVyc2VjdChncDJjNyxncDJjMTIpCnM1PC1ncDJjN1shKGdwMmM3ICVpbiUgczQpXQpzNjwtZ3AyYzEyWyEoZ3AyYzEyICVpbiUgczQpXQpzNzwtZ3AxYzcKczg8LWdwMWMxMgoKY2FHcm91cDwtZGF0YS5mcmFtZShjbHVzdGVyPWMocmVwKCJib3RoLWludiIsIHRpbWVzPWxlbmd0aChzMSkpLHJlcCgiYzctaW52IiwgdGltZXM9bGVuZ3RoKHMyKSkscmVwKCJjMTItaW52IiwgdGltZXM9bGVuZ3RoKHMzKSkscmVwKCJib3RoLWhldCIsIHRpbWVzPWxlbmd0aChzNCkpLHJlcCgiYzctaGV0IiwgdGltZXM9bGVuZ3RoKHM1KSkscmVwKCJjMTItaGV0IiwgdGltZXM9bGVuZ3RoKHM2KSkscmVwKCJjNy1jb21tb24iLCB0aW1lcz1sZW5ndGgoczcpKSxyZXAoImMxMi1jb21tb24iLCB0aW1lcz1sZW5ndGgoczgpKSksU2FtcGxlPWMoczEsczIsczMsczQsczUsczYsczcsczgpICkKCkNBc3VtPC1kYXRhLmZyYW1lKHRhYmxlKGNhR3JvdXAkY2x1c3RlcikpCgojIENvbXB1dGUgdGhlIHBvc2l0aW9uIG9mIGxhYmVscwpDQXN1bSRWYXIxPC1mYWN0b3IoQ0FzdW0kVmFyMSwgbGV2ZWxzPWMoImJvdGgtaW52IiwgImM3LWludiIsImMxMi1pbnYiLCJib3RoLWhldCIsImM3LWhldCIsImMxMi1oZXQiLCJjNy1jb21tb24iLCJjMTItY29tbW9uIikpCkNBc3VtPC1DQXN1bVtvcmRlcihDQXN1bSRWYXIxKSxdCkNBc3VtPC0gQ0FzdW0gJT4lIAogIGFycmFuZ2UoZGVzYyhWYXIxKSkgJT4lCiAgbXV0YXRlKHByb3AgPSBGcmVxIC8gc3VtKENBc3VtJEZyZXEpICoxMDApICU+JQogIG11dGF0ZSh5cG9zID0gY3Vtc3VtKHByb3ApLSAwLjUqcHJvcCApCgpnZ3Bsb3QoQ0FzdW0sIGFlcyh4PSIiLCB5PUZyZXEsIGZpbGw9VmFyMSkpKwogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCB3aWR0aD0xLGNvbG9yPSJ3aGl0ZSIpKwogICAgY29vcmRfcG9sYXIoInkiLCBzdGFydD0wLCBkaXJlY3Rpb249LTEpK3RoZW1lX3ZvaWQoKSsKICAgIGdlb21fdGV4dChhZXMoeD0xLjYseSA9IHlwb3MsIGxhYmVsID0gVmFyMSksIGNvbG9yID0gImdyYXkyMCIsIHNpemU9NCkgKwogICAgIGdlb21fdGV4dChhZXMoeD0xLCBsYWJlbCA9IHBhc3RlMChyb3VuZChwcm9wLCBkaWdpdHMgPSAxKSwgIiAlIikpLCBjb2xvciA9ICJncmF5MjAiLCBzaXplPTMsIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAuNSkgKSArCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJTZXQzIiwgZ3VpZGU9J25vbmUnKQpnZ3NhdmUoIi4uL091dHB1dC9QQ0EvQ0FfYzctYzEyLWludmVyc2lvbi1ncm91cHNfcGllY2hhcnQucG5nIiwgd2lkdGggPSA1LCBoZWlnaHQ9NSwgZHBpPTMwMCkKYGBgCgohW10oLi4vT3V0cHV0L1BDQS9DQV9jNy1jMTItaW52ZXJzaW9uLWdyb3Vwc19waWVjaGFydC5wbmcpCgojIyMgUFdTIHBvcHVsYXRpb24KCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KY29sb3JzPC1xdWFsaXRhdGl2ZV9oY2woOCwgcGFsZXR0ZT0iRGFyazMiKQoKI3BjYWNvbHM8LWMoIiNmYmI0YWUiLCIjYjNjZGUzIiwiI2NjZWJjNSIpCiNwb3BfaW5mbzwtcmVhZC5jc3YoIi4uL0RhdGEvU2FtcGxlX21ldGFkYXRhXzg5MnBvcHMuY3N2IikKI3BvcHM8LXVuaXF1ZShwb3BfaW5mbyRQb3B1bGF0aW9uLlllYXIpCnBjYTc8LXJlYWQuY3N2KCIuLi9PdXRwdXQvUENBL2NocjdfUENBZ3JvdXBzLmNzdiIsIHJvdy5uYW1lcyA9IDEpCnBjYTEyPC1yZWFkLmNzdigiLi4vT3V0cHV0L1BDQS9jaHIxMl9QQ0Fncm91cHMuY3N2Iiwgcm93Lm5hbWVzID0gMSkKCiMyLiBQV1MgcG9wdWxhdGlvbnMKcHdzczwtYygiUFdTOTEiLCJQV1M5NiIsIlBXUzA3IiwiUFdTMTciKQojZ3JvdXAyCmZvcihpIGluIDE6bGVuZ3RoKHB3c3MpKXsKICAgIGdwMmM3PC0gcGNhNyRTYW1wbGVbcGNhNyRHcm91cD09Ikdyb3VwMiImcGNhNyR5ci5wb3A9PXB3c3NbaV1dIAogICAgZ3AyYzEyPC1wY2ExMiRTYW1wbGVbcGNhMTIkR3JvdXA9PSJHcm91cDIiJnBjYTEyJHlyLnBvcD09cHdzc1tpXV0gCiAgICB4MjwtbGlzdChjaHI3PWdwMmM3LGNocjEyPWdwMmMxMikKICAgIHAyPC1nZ3Zlbm4oeDIsIGZpbGxfY29sb3IgPSBjb2xzLCBzdHJva2Vfc2l6ZSA9IDAuNSwgc2V0X25hbWVfc2l6ZSA9IDQsdGV4dF9zaXplPTMpK2dndGl0bGUoIkdyb3VwMiIpCgogICAgZ3AxYzc8LSBwY2E3JFNhbXBsZVtwY2E3JEdyb3VwPT0iR3JvdXAxIiZwY2E3JHlyLnBvcD09cHdzc1tpXV0KICAgIGdwMWMxMjwtcGNhMTIkU2FtcGxlW3BjYTEyJEdyb3VwPT0iR3JvdXAxIiZwY2ExMiR5ci5wb3A9PXB3c3NbaV1dCiAgICB4MTwtbGlzdChjaHI3PWdwMWM3LGNocjEyPWdwMWMxMikKICAgIHAxPC1nZ3Zlbm4oeDEsIGZpbGxfY29sb3IgPSBjb2xvcnMsc3Ryb2tlX3NpemUgPSAwLjUsIHNldF9uYW1lX3NpemUgPSA0LHRleHRfc2l6ZT0zKStnZ3RpdGxlKCJHcm91cDEiKQogICAgCiAgICB2ZW5uPC1nZ2RyYXcoKSsKICAgICAgICBkcmF3X3Bsb3QocDEseD0wLHk9MCx3aWR0aD0wLjUsaGVpZ2h0PTEpKwogICAgICAgIGRyYXdfcGxvdChwMiwwLjUsMCwwLjUsMSkrCiAgICAgICAgZHJhd19wbG90X2xhYmVsKHB3c3NbaV0sIHg9LTAuMDUsIHk9MC45NSwgc2l6ZSA9IDE1KQogICAgc2F2ZV9wbG90KGZpbGVuYW1lID1wYXN0ZTAoIi4uL091dHB1dC9QQ0EvIixwd3NzW2ldLCJfZ3JvdXBfb3ZlcmxhcC5wbmciKSwgcGxvdCA9IHZlbm4sYmFzZV93aWR0aCA9IDcsIGJhc2VfaGVpZ2h0ID0gNSwgZHBpPTMwMCkgICAKfQpgYGAKCgohW10oLi4vT3V0cHV0L1BDQS9QV1M5MV9ncm91cF9vdmVybGFwLnBuZykgIAohW10oLi4vT3V0cHV0L1BDQS9QV1M5Nl9ncm91cF9vdmVybGFwLnBuZykgIAohW10oLi4vT3V0cHV0L1BDQS9QV1MwN19ncm91cF9vdmVybGFwLnBuZykgIAohW10oLi4vT3V0cHV0L1BDQS9QV1MxN19ncm91cF9vdmVybGFwLnBuZykgIAoKCiMjIyMgSW5kaXZpZHVsYXMgd2l0aCBjaHIxMiBpbnZlcnNpb24gYW5kIGNocjcgaW52ZXJzaW9uIGRvIG5vdCBvdmVyYWxhcC4KCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmBgYAoKYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKYGBgCg==